/*
 * Copyright © 2009 Perseus Project - Tufts University <http://www.perseus.tufts.edu>
 *
 * This file is part of TranscoderPerseus.
 *
 * TranscoderPerseus is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * TranscoderPerseus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with TranscoderPerseus.  If not, see <http://www.gnu.org/licenses/>.
 * This class is based on:
 * DefaultHandler.java - default implementation of the core handlers.
 * http://www.saxproject.org
 * Written by David Megginson (NO WARRANTY!  This class is in the public domain).
 */

package eu.himeros.transcoder;

import java.io.BufferedWriter;
import java.io.IOException;

import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.DefaultHandler2;
import org.xml.sax.ext.EntityResolver2;
import org.xml.sax.ext.LexicalHandler;

public class TransHandler extends DefaultHandler2 implements LexicalHandler, DeclHandler, EntityResolver2 {

    protected StringBuffer sb = null;
    protected BufferedWriter bw=null;

    protected boolean writeNotationDecl=false;
    protected boolean writeUnparsedEntityDecl=false;
    protected boolean writeSetDocumentLocator=false;
    protected boolean writeStartDocument=false;
    protected boolean writeEndDocument=false;
    protected boolean writeStartPrefixMapping=false;
    protected boolean writeEndPrefixMapping=false;
    protected boolean writeStartElement=false;
    protected boolean writeEndElement=false;
    protected boolean writeCharacters=false;
    protected boolean writeIgnorableWhiteSpaces=false;
    protected boolean writeProcessingInstruction=false;
    protected boolean writeSkippedEntity=false;
    protected boolean writeWarning=false;
    protected boolean writeError=false;
    protected boolean writeFatalError=false;
    protected boolean writeStartCDATA=false;
    protected boolean writeEndCDATA=false;
    protected boolean writeStartDTD=false;
    protected boolean writeEndDTD=false;
    protected boolean writeStartEntity=false;
    protected boolean writeEndEntity=false;
    protected boolean writeComment=false;
    protected boolean writeAttributeDecl=false;
    protected boolean writeElementDecl=false;
    protected boolean writeExternalEntityDecl=false;
    protected boolean writeInternalEntityDecl=false;
    protected boolean writeGetExternalSubset=false;
    protected boolean writeResolveEntity=false;

    /**
     *
     * @param name
     * @param publicId
     * @param systemId
     * @throws org.xml.sax.SAXException
     */
    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeNotationDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param publicId
     * @param systemId
     * @param notationName
     * @throws org.xml.sax.SAXException
     */
    public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeUnparsedEntityDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param locator
     */
    public void setDocumentLocator(Locator locator) {
        sb=new StringBuffer("");
        try{if(writeSetDocumentLocator) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @throws org.xml.sax.SAXException
     */
    public void startDocument() throws SAXException {
        sb=new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        try{if(true){bw.write(sb.toString());bw.newLine();}}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @throws org.xml.sax.SAXException
     */
    public void endDocument() throws SAXException {
        sb=new StringBuffer("");
        try{if(writeEndDocument) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param prefix
     * @param uri
     * @throws org.xml.sax.SAXException
     */
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeStartPrefixMapping) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param prefix
     * @throws org.xml.sax.SAXException
     */
    public void endPrefixMapping(String prefix) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeEndPrefixMapping) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws org.xml.sax.SAXException
     */
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        sb = new StringBuffer();
        sb.append("<" + qName);
        for (int i = 0; i < attributes.getLength(); i++) {
            sb.append(" " + attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\"");
        }
        sb.append(">");
        try{if(writeStartElement) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param uri
     * @param localName
     * @param qName
     * @throws org.xml.sax.SAXException
     */
    public void endElement(String uri, String localName, String qName) throws SAXException {
        sb = new StringBuffer();
        sb.append("</" + qName + ">");
        try{if(writeEndElement) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param ch
     * @param start
     * @param length
     * @throws org.xml.sax.SAXException
     */
    public void characters(char ch[], int start, int length) throws SAXException {
        sb=new StringBuffer(new String(ch,start,length));
        try{if(writeCharacters) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param ch
     * @param start
     * @param length
     * @throws org.xml.sax.SAXException
     */
    public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
        sb = new StringBuffer(new String(ch, start, length));
        try{if(writeStartElement) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param target
     * @param data
     * @throws org.xml.sax.SAXException
     */
    public void processingInstruction(String target, String data) throws SAXException {
        sb = new StringBuffer("<?" + target + " " + data + "?>");
        try{if(writeProcessingInstruction) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @throws org.xml.sax.SAXException
     */
    public void skippedEntity(String name) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeSkippedEntity) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @throws org.xml.sax.SAXException
     */
    public void startCDATA() throws SAXException {
        sb=new StringBuffer("<![CDATA[");
        try{if(writeStartCDATA) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @throws org.xml.sax.SAXException
     */
    public void endCDATA() throws SAXException {
        sb=new StringBuffer("]]>");
        try{if(writeEndCDATA) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param publicId
     * @param systemId
     * @throws org.xml.sax.SAXException
     */
    public void startDTD(String name, String publicId, String systemId) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeStartDTD) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @throws org.xml.sax.SAXException
     */
    public void endDTD() throws SAXException {
        sb=new StringBuffer("");
        try{if(writeEndDTD) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @throws org.xml.sax.SAXException
     */
    public void startEntity(String name) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeStartEntity) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @throws org.xml.sax.SAXException
     */
    public void endEntity(String name) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeEndEntity) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param ch
     * @param start
     * @param length
     * @throws org.xml.sax.SAXException
     */
    public void comment(char ch[], int start, int length) throws SAXException {
        sb=new StringBuffer("<!--"+new String(ch, start, length)+"-->");
        try{if(writeComment) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param eName
     * @param aName
     * @param type
     * @param mode
     * @param value
     * @throws org.xml.sax.SAXException
     */
    public void attributeDecl(String eName, String aName, String type, String mode, String value) throws SAXException {
        // SAX2 ext-1.0 DeclHandler
        sb=new StringBuffer("");
        try{if(writeAttributeDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param model
     * @throws org.xml.sax.SAXException
     */
    public void elementDecl(String name, String model) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeElementDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param publicId
     * @param systemId
     * @throws org.xml.sax.SAXException
     */
    public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeExternalEntityDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param value
     * @throws org.xml.sax.SAXException
     */
    public void internalEntityDecl(String name, String value) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeInternalEntityDecl) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param name
     * @param baseURI
     * @return
     * @throws org.xml.sax.SAXException
     * @throws java.io.IOException
     */
    public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException {
        // SAX2 ext-1.1 EntityResolver
        sb=new StringBuffer("");
        try{if(writeGetExternalSubset) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
        return null;
    }

    /**
     *
     * @param name
     * @param publicId
     * @param baseURI
     * @param systemId
     * @return
     * @throws org.xml.sax.SAXException
     * @throws java.io.IOException
     */
    public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException {
        sb=new StringBuffer("");
        try{if(writeResolveEntity) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
        return null;
    }

    /**
     *
     * @param publicId
     * @param systemId
     * @return
     * @throws org.xml.sax.SAXException
     * @throws java.io.IOException
     */
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        sb=new StringBuffer("");
        try{if(writeResolveEntity) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
        return resolveEntity(null, publicId, null, systemId);
    }

    /**
     *
     * @param e
     * @throws org.xml.sax.SAXException
     */
    public void warning(SAXParseException e) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeWarning) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param e
     * @throws org.xml.sax.SAXException
     */
    public void error(SAXParseException e) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeError) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param e
     * @throws org.xml.sax.SAXException
     */
    public void fatalError(SAXParseException e) throws SAXException {
        sb=new StringBuffer("");
        try{if(writeFatalError) bw.write(sb.toString());}catch(Exception ex){ex.printStackTrace();}
        throw e;
    }

}
